/*****************************************
**  Nom : RASPAUD - COLLOMB				**
**	Nom du fichier : DrlmntPartie.c		**
**	Description : Regroupement de 		**
**		toutes les fonctions pour le 	**
**		deroulement du jeu				**
**										**
**										**
**	Date : 20/08/2014				    **
**  Statut : Release					**
*****************************************/

/*****************************************
**  Zone de declaration des includes    **
*****************************************/
#include "struct.h"

/*************************************************
**  Zone de declaration des Fonctions PUBLIC    **
*************************************************/

/*************************************************************************
**  [Fonction DrlmntPartie_ConvCarte]                					**
**  Convertie les chiffres contenuent dans les structures "S_CARTE" en	** 
**	chaine de caractere pour pouvoir les lires et les afficher durant	**
**  une partie									    				    **
**																		**
**	Entrees : S_CARTE* carte - Carte à afficher	                        **
**			: FIFO_PAQUET paquet - FIFO dans laquel est presente la		**
**			  carte Ã  convertir										**
**																		**
**	Sorties : int														**
**									                                    **
**************************************************************************/
int DrlmntPartie_ConvCarte(S_CARTE* carte,FIFO_PAQUET paquet)
{
	switch(carte->valeur)
		{
			case 0:
				break;
			case 1:
				printf("AS ");
				break;
			case 2:
				printf("2 ");
				break;
			case 3:
				printf("3 ");
				break;
			case 4:
				printf("4 ");
				break;
			case 5:
				printf("5 ");
				break;
			case 6:
				printf("6 ");
				break;
			case 7:
				printf("7 ");
				break;
			case 8:
				printf("8 ");
				break;
			case 9:
				printf("9 ");
				break;
			case 10:
				printf("10 ");
				break;
			case 11:
				printf("VALET ");
				break;
			case 12:
				printf("DAME ");
				break;
			case 13:
				printf("ROI ");
				break;
			default:
				printf("DrlmntPartie_ConvCarte : Erreur !\n");
				return -1;
		}	
		
		switch(carte->signe)
		{
			case 0:
				break;
			case 1:
				printf("COEUR................\n");	
				break;
			case 2:
				printf("CARREAU................\n");
				break;
			case 3:
				printf("PIQUE................\n");
				break;
			case 4:
				printf("TREFLE................\n");
				break;
			default:
				printf("DrlmntPartie_ConvCarte : Erreur !\n");
				return -1;
		}
		
		/*switch(paquet.nom_joueur)
		{
			case 0:
				printf("à Table\n");
				break;
			case 1:
				printf("Joueur 1\n");
				break;
			case 2:
				printf("Joueur 2\n");
				break;
			case 3:
				printf("Joueur 3\n");
				break;
			case 4:
				printf("Joueur 4\n");
				break;
			default:
				printf("DrlmntPartie_ConvCarte : Erreur !\n");
				return -1;
		}*/
	return 0;
}


/*************************************************************************
**  [Fonction DrlmntPartie_EchgFIFOin]                					**
**  Prend la premiere carte d'une FIFO et la transfert en premiere 		**
**  place dans une autre FIFO					    				    **
**																		**
**	Entrees : FIFO_PAQUET *paquet_donneur 		                        **
**			: FIFO_PAQUET *paquet_receveur								**
**																		**
**	Sorties : int														**
**					-1 si erreur										**
**					 0 si ok											**
**									                                    **
**************************************************************************/
int DrlmntPartie_EchgFIFOin(FIFO_PAQUET *paquet_donneur, FIFO_PAQUET *paquet_receveur)
{
	S_CARTE *copie_nouvelle_carte=NULL,*copie=NULL;
	
	if(paquet_receveur->nb_carte==0)
	{
		//printf("DrlmntPartie_EchgFIFOin : le paquets du receveur est vide ! Remise à zéro de la FIFO\n");
		*paquet_receveur=InitPartie_InitFIFO(paquet_receveur->nom_joueur);
	}
	if(paquet_donneur->carte_in!=NULL && paquet_receveur->carte_in!=NULL && paquet_receveur->carte_out!=NULL) //paquet receveur non vide
	{
		//printf("DrlmntPartie_EchgFIFOin : début échange carte du paquet cible !\n");
		paquet_donneur->nb_carte--;
		paquet_receveur->nb_carte++;
		
		copie_nouvelle_carte=paquet_donneur->carte_in;
		paquet_donneur->carte_in=paquet_donneur->carte_in->carte_suivante;
	
		copie=paquet_receveur->carte_in;
		paquet_receveur->carte_in=copie_nouvelle_carte;
		paquet_receveur->carte_in->carte_suivante=copie;
		//printf("DrlmntPartie_EchgFIFOin : fin échange carte du paquet cible !\n");
		return 0;
	}
	if(paquet_donneur->carte_in!=NULL && paquet_receveur->carte_in==NULL && paquet_receveur->carte_out==NULL) //paquet receveur est vide
	{
		//printf("DrlmntPartie_EchgFIFOin : début échange 1ere carte du paquet cible !\n");
		paquet_donneur->nb_carte--;
		paquet_receveur->nb_carte++;
		
		copie=paquet_donneur->carte_in;
		
		paquet_donneur->carte_in=paquet_donneur->carte_in->carte_suivante;
		
		paquet_receveur->carte_in=copie;
		paquet_receveur->carte_out=copie;
		
		paquet_receveur->carte_in->carte_suivante=NULL;
		paquet_receveur->carte_out->carte_suivante=NULL;
		//printf("DrlmntPartie_EchgFIFOin : début échange 1ere carte du paquet cible !\n");
		return 0;
	}
	printf("DrlmntPartie_EchgFIFOout : Erreur ; Aucun cas trouvé !\n");
	return -1;
}


/*************************************************************************
**  [Fonction DrlmntPartie_EchgFIFOout]                					**
**  Prend la premiere carte d'une FIFO et la transfert en derniere 		**
**  place dans une autre FIFO					    				    **
**																		**
**	Entrees : FIFO_PAQUET *paquet_donneur 		                        **
**			: FIFO_PAQUET *paquet_receveur								**
**																		**
**	Sorties : int														**
**					-1 si erreur										**
**					 0 si ok											**
**																		**
**************************************************************************/
int DrlmntPartie_EchgFIFOout(FIFO_PAQUET *paquet_donneur, FIFO_PAQUET *paquet_receveur)
{
	S_CARTE *copie_nouvelle_carte=NULL,*copie=NULL;
	
	if(paquet_receveur->nb_carte==0)
	{
		//printf("DrlmntPartie_EchgFIFOout : le paquets du receveur est vide ! Remise à zéro de la FIFO\n");
		*paquet_receveur=InitPartie_InitFIFO(paquet_receveur->nom_joueur);
	}
	if(paquet_donneur->carte_in!=NULL && paquet_receveur->carte_in!=NULL && paquet_receveur->carte_out!=NULL) //paquet receveur non vide
	{
		//printf("DrlmntPartie_EchgFIFOout : début échange carte du paquet cible !\n");
		paquet_donneur->nb_carte--;
		paquet_receveur->nb_carte++;
		
		copie_nouvelle_carte=paquet_donneur->carte_in;
		paquet_donneur->carte_in=paquet_donneur->carte_in->carte_suivante;
	
		paquet_receveur->carte_out->carte_suivante=copie_nouvelle_carte;
		paquet_receveur->carte_out=copie_nouvelle_carte;
		paquet_receveur->carte_out->carte_suivante=NULL;
		//printf("DrlmntPartie_EchgFIFOout : fin échange carte du paquet cible !\n");
		return 0;
	}
	if(paquet_donneur->carte_in!=NULL && paquet_receveur->carte_in==NULL && paquet_receveur->carte_out==NULL) //paquet receveur est vide
	{
		//printf("DrlmntPartie_EchgFIFOout : début échange 1ere carte du paquet cible !\n");
		paquet_donneur->nb_carte--;
		paquet_receveur->nb_carte++;
		
		copie=paquet_donneur->carte_in;
		
		paquet_donneur->carte_in=paquet_donneur->carte_in->carte_suivante;
		
		paquet_receveur->carte_in=copie;
		paquet_receveur->carte_out=copie;
		
		paquet_receveur->carte_in->carte_suivante=NULL;
		paquet_receveur->carte_out->carte_suivante=NULL;
		//printf("DrlmntPartie_EchgFIFOout : début échange 1ere carte du paquet cible !\n");
		return 0;
	}
	printf("DrlmntPartie_EchgFIFOout : Erreur ; Aucun cas trouvé !\n");
	return -1;
}


/*************************************************************************
**  [Fonction DrlmntPartie_Random]    	            					**
**   Renvoi un nombre aleatoire compris entre 1 et le max				**
**																		**	
**	 srand(time(NULL)); --> cette ligne doit apparaitre dans le			**
**   programme "main" avant d'appeler la fonction "DrlmntPartie_Random" **
**																		**
**	Entrees : int nombre_joueur 		 		                        **
**																		**
**																		**
**	Sorties : int														**
**					Nombre aleatoire									**
**																		**
**************************************************************************/
int DrlmntPartie_Random(int nombre_joueur)
{
	if(nombre_joueur<1 || nombre_joueur>NOMBRE_JOUEUR_MAX)
	{
		printf("DrlmntPartie_Random : Erreur ! Mauvaise valeur envoyée à la fonction !\n");
		return 0;
	}
	else
	{
		return (NUMERO_PREMIER_JOUEUR + (rand() % (nombre_joueur-NUMERO_PREMIER_JOUEUR+1)));
	}
	return 0;
}


/*************************************************************************
**  [Fonction DrlmntPartie_ReturnCarte]             					**
**   Renvoi les 3 premieres cartes du paquet							**
**																		**	
**																		**
**	Entrees : FIFO_PAQUET *paquet 										**
**			: int valeur_cartes[] - Tableau avec au moins 3 cases, 		**
**				qui contiendra les valeurs des 3 dernieres cartes       **
**																		**
**																		**
**	Sorties : int														**
**					-1 si erreur										**
**					 0 si ok											**
**																		**
**************************************************************************/
int DrlmntPartie_ReturnCarte(FIFO_PAQUET *paquet, int valeur_cartes[])
{
	S_CARTE *courant;
	
	//printf("DrlmntPartie_ReturnCarte : Début fonction\n");
	if(paquet->carte_in!=NULL && paquet->carte_out!=NULL)
	{
		courant=paquet->carte_in;
		valeur_cartes[0]=courant->valeur; //sauvegarde de la 1ere carte
		if(courant->carte_suivante==NULL)
		{
			//printf("DrlmntPartie_ReturnCarte : il n'y avait qu'une seule carte dans le paquet\n");
			valeur_cartes[1]=0;
			valeur_cartes[2]=0;
			return 0;
		}
		else
		{
			courant=courant->carte_suivante;
			valeur_cartes[1]=courant->valeur; //sauvegarde de la 2eme carte
			if(courant->carte_suivante==NULL)
			{
				//printf("DrlmntPartie_ReturnCarte : il n'y avait que deux cartes dans le paquet\n");
				valeur_cartes[2]=0;
				return 0;
			}
			else
			{
				courant=courant->carte_suivante;
				valeur_cartes[2]=courant->valeur; //sauvegarde de la 3eme carte	
				//printf("DrlmntPartie_ReturnCarte : Toute les valeurs des cartes sont enregistrées\n");
				//printf("DrlmntPartie_ReturnCarte : Fin fonction\n");
				return 0;
			}
		}
	}
	if(paquet->carte_in==NULL || paquet->carte_out==NULL)
	{
		//printf("DrlmntPartie_ReturnCarte : Erreur la FIFO est vide !\n");
		valeur_cartes[0]=0;
		valeur_cartes[1]=0;
		valeur_cartes[2]=0;
		return 0;
	}
	return -1;
}


/*************************************************************************
**  [Fonction DrlmntPartie_ViderTable]             					    **
**   Renvoi les 3 premieres cartes du paquet							**
**																		**	
**																		**
**	Entrees : FIFO_PAQUET *table										**
**			: FIFO_PAQUET *paquet_receveur						 		**
**																        **
**																		**
**																		**
**	Sorties : int														**
**					-1 si erreur										**
**					 0 si ok											**
**																		**
**************************************************************************/
int DrlmntPartie_ViderTable(FIFO_PAQUET *table, FIFO_PAQUET *paquet_receveur)
{
	int test=-1;
	
	//printf("DrlmntPartie_ViderTable : Début Fonction \n");
	if(table->nb_carte==0)
	{
		printf("DrlmntPartie_ViderTable : FIFO 'table' vide !\n");
		return -1;
	}
	
	while(table->nb_carte!=0)
	{
		test=DrlmntPartie_EchgFIFOout(table,paquet_receveur);
		if(test==-1)
		{
			printf("DrlmntPartie_ViderTable : Erreur dans la fonction 'DrlmntPartie_EchgFIFOout' !\n");
			return -1;
		}
	}
	*table=InitPartie_InitFIFO(0); //permet de repartir sur une base propre
	//printf("DrlmntPartie_ViderTable : Fin Fonction \n");
	return 0;
}


/*************************************************************************
**  [Fonction DrlmntPartie_AfficheFIFO]             					**
**   Renvoi les 3 premieres cartes du paquet							**
**																		**	
**																		**
**	Entrees : FIFO_PAQUET *FIFO											**
**																 		**
**																        **
**																		**
**																		**
**	Sorties : int														**
**					-1 si erreur										**
**					 0 si ok											**
**																		**
**************************************************************************/
int DrlmntPartie_AfficheFIFO(FIFO_PAQUET *FIFO)
{
	S_CARTE *carte=NULL;
	int test=-1;
	
	//printf("DrlmntPartie_AfficheFIFO : Début Fonction \n");
	if(FIFO->nb_carte==0)
	{
		//printf("DrlmntPartie_AfficheFIFO : FIFO à lire vide !\n");
		return 0;
	}	
	
	carte=FIFO->carte_in;
	//printf("DrlmntPartie_AfficheFIFO : table.nb_carte = %d \n",table.nb_carte);
	while(carte!=NULL)
	{
		test=DrlmntPartie_ConvCarte(carte,*FIFO);
		if(test==-1)
		{
			printf("DrlmntPartie_AfficheFIFO : Erreur de la fonction 'DrlmntPartie_ConvCarte' ! \n");
			return -1;
		}
		carte=carte->carte_suivante;
	}
	//printf("DrlmntPartie_AfficheFIFO : Fin Fonction \n");
	return 0;
}

/*************************************************************************
**  [Fonction DrlmntPartie_MAJfaits]             						**
**   Met a jour la liste de fait en fonction des 3 derniere cartes		**
**	 sur la table														**	
**																		**
**	Entrees : ST_RES* Tete de la chaine de resultats					**
**			: ST_FAITS* Tete de la chaine de faits						**
**																		**
**																		**
**	Sorties : int														**
**				-1 Erreur												**
**				 0 OK													**
**																		**
**************************************************************************/
int DrlmntPartie_MAJfaits(FIFO_PAQUET* Table,ST_FAITS* Tete_fait)
{
	int Last_3_Values[LAST_CARDS];
	int idx=0;
	char Temp_String[MAXSIZE];
	FIFO_PAQUET* tmp_Table;
	ST_FAITS* tmp_fait;
	
	memset(Temp_String,0,sizeof(Temp_String));
	
	if(Table == NULL || Tete_fait == NULL)
	{
		printf("Erreur de pointeur\n");
		return -1;
	}
	
	tmp_Table = Table;
	tmp_fait = Tete_fait;
	DrlmntPartie_ReturnCarte(tmp_Table,Last_3_Values);
	//printf("Valeurs retournées ! carte 1=%d ; cartes 2=%d ; cartes 3=%d\n",Last_3_Values[0],Last_3_Values[1],Last_3_Values[2]);
	
	while(strcmp(tmp_fait->fait , SEPARATEUR) != 0)
	{
		tmp_fait = tmp_fait->suiv;
		if(tmp_fait == NULL)
			return -1;
	}
	
	//printf("Le separateur été trouvé => <%s>\n",tmp_fait->fait);
	for(idx = 0;idx<3;idx++)
	{
		if(Last_3_Values[idx] == 0)
			continue;
			
		sprintf(Temp_String, "%d_%d",Last_3_Values[idx],3-idx);
				
		if(tmp_fait->suiv == NULL)
		{
			CreerListeCh_Creer_MaillonFaits(Tete_fait, Temp_String);
		}
		else
		{
			strcpy(tmp_fait->suiv->fait,Temp_String);
		}
		tmp_fait = tmp_fait->suiv;
	}
	return 0;		
}

/*************************************************************************
**  [Fonction DrlmntPartie_CLEANfaits]             						**
**   Met a jour la liste de fait en fonction des 3 derniere cartes		**
**	 sur la table														**	
**																		**
**	Entrees	: ST_FAITS* Tete de la chaine de faits						**
**																		**
**																		**
**																		**
**	Sorties : int														**
**				-1 Erreur												**
**				 0 OK													**
**																		**
**************************************************************************/
int DrlmntPartie_CLEANfaits(ST_FAITS* Tete_fait)
{
	ST_FAITS* tmp_fait=NULL;
	ST_FAITS* tmp_faitBis=NULL;
	ST_FAITS* tmp_faitSep=NULL;
	
	if(Tete_fait == NULL)
	{
		printf("Erreur de pointeur\n");
		return -1;
	}
	tmp_fait = Tete_fait;

	while(strcmp(tmp_fait->fait , SEPARATEUR) != 0)
	{
		tmp_fait = tmp_fait->suiv;
		if(tmp_fait == NULL)
			return -1;
	}
	tmp_faitSep = tmp_fait;
	tmp_fait = tmp_fait->suiv;
	
	if (tmp_fait != NULL)
	{
		while(tmp_fait != NULL)
		{
			tmp_faitBis=tmp_fait->suiv;
			free(tmp_fait);
			tmp_fait=tmp_faitBis;
		}
			tmp_faitSep->suiv = NULL;
	}	
	printf("Nettoyage des FAITS OK\n");		
	return 0;
}

/*************************************************************************
**  [Fonction DrlmntPartie_Affiche3Cartes]             					**
**  Affiche les 3 dernieres cartes qui sont sur le paquet pour que les	**
**	joueurs puissent voir les cartes en jeux correctement 				**	
**																		**
**	Entrees	: FIFO_PAQUET *table : FIFO du paquet "table"				**
**																		**
**																		**
**																		**
**	Sorties : int														**
**				-1 Erreur												**
**				 0 OK													**
**																		**
**************************************************************************/
int DrlmntPartie_Affiche3Cartes(FIFO_PAQUET *table)
{
	int valeur_cartes[3],signe_cartes[3],test=-1;
	S_CARTE carte;
	
	memset(valeur_cartes,0,sizeof(valeur_cartes));
	memset(signe_cartes,0,sizeof(signe_cartes));
	test=DrlmntPartie_ReturnCarte(table,valeur_cartes);
	if(test==-1)
	{
		printf("DrlmntPartie_Affiche3Cartes : Erreur lors du retour de la fonction 'DrlmntPartie_ReturnCarte' !\n");
		return -1;
	}
	test=DrlmntPartie_ReturnSigne(table,signe_cartes);
	if(test==-1)
	{
		printf("DrlmntPartie_Affiche3Cartes : Erreur lors du retour de la fonction 'DrlmntPartie_ReturnCarte' !\n");
		return -1;
	}
	
	printf("\n");
	printf("Cartes sur la table :\n");
	printf("\n");
	
	printf("			");
	carte.valeur=valeur_cartes[0];
	carte.signe=signe_cartes[0];
	test=DrlmntPartie_ConvCarte(&carte,*table);
	if(test==-1)
	{
		printf("DrlmntPartie_Affiche3Cartes : Erreur lors du retour de la fonction 'DrlmntPartie_ConvCarte' !\n");
		return -1;
	}
	
	printf("			");
	carte.valeur=valeur_cartes[1];
	carte.signe=signe_cartes[1];
	test=DrlmntPartie_ConvCarte(&carte,*table);
	if(test==-1)
	{
		printf("DrlmntPartie_Affiche3Cartes : Erreur lors du retour de la fonction 'DrlmntPartie_ConvCarte' !\n");
		return -1;
	}
	
	printf("			");
	carte.valeur=valeur_cartes[2];
	carte.signe=signe_cartes[2];
	test=DrlmntPartie_ConvCarte(&carte,*table);
	if(test==-1)
	{
		printf("DrlmntPartie_Affiche3Cartes : Erreur lors du retour de la fonction 'DrlmntPartie_ConvCarte' !\n");
		return -1;
	}
	
	printf("\n");
	return 0;
}

/*************************************************************************
**  [Fonction DrlmntPartie_ReturnSigne]             					**
**   Renvoi les signes 3 premieres cartes du paquet						**
**																		**	
**																		**
**	Entrees : FIFO_PAQUET *paquet 										**
**			: int vsigne_cartes[] - Tableau avec au moins 3 cases, 		**
**				qui contiendra les valeurs des 3 dernieres cartes       **
**																		**
**																		**
**	Sorties : int														**
**					-1 si erreur										**
**					 0 si ok											**
**																		**
**************************************************************************/
int DrlmntPartie_ReturnSigne(FIFO_PAQUET *paquet, int signe_cartes[])
{
	S_CARTE *courant;
	
	//printf("DrlmntPartie_ReturnCarte : Début fonction\n");
	if(paquet->carte_in!=NULL && paquet->carte_out!=NULL)
	{
		courant=paquet->carte_in;
		signe_cartes[0]=courant->signe; //sauvegarde de la 1ere carte
		if(courant->carte_suivante==NULL)
		{
			//printf("DrlmntPartie_ReturnCarte : il n'y avait qu'une seule carte dans le paquet\n");
			signe_cartes[1]=0;
			signe_cartes[2]=0;
			return 0;
		}
		else
		{
			courant=courant->carte_suivante;
			signe_cartes[1]=courant->signe; //sauvegarde de la 2eme carte
			if(courant->carte_suivante==NULL)
			{
				//printf("DrlmntPartie_ReturnCarte : il n'y avait que deux cartes dans le paquet\n");
				signe_cartes[2]=0;
				return 0;
			}
			else
			{
				courant=courant->carte_suivante;
				signe_cartes[2]=courant->signe; //sauvegarde de la 3eme carte	
				//printf("DrlmntPartie_ReturnCarte : Toute les valeurs des cartes sont enregistrées\n");
				//printf("DrlmntPartie_ReturnCarte : Fin fonction\n");
				return 0;
			}
		}
	}
	if(paquet->carte_in==NULL || paquet->carte_out==NULL)
	{
		//printf("DrlmntPartie_SigneCarte : Erreur la FIFO est vide !\n");
		signe_cartes[0]=0;
		signe_cartes[1]=0;
		signe_cartes[2]=0;
		return 0;
	}
	return -1;
}
